home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Snippets / Toolbox / Scrap Parsing / simple.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-24  |  24.8 KB  |  662 lines  |  [TEXT/MPS ]

  1. /* Simple.c */
  2. /* The simplest C System 7 shell application */
  3. /* This shell can be very handy for debugging and testing things */
  4. /* Add menu items, add dialogs, add controls, or whatever else you need */
  5. /* This sample contains basic application startup and event loop handling, */
  6. /* add more features as your needs increase. */
  7. /* This sample is High Level Event aware, so you can send and receive AppleEvents */
  8. /* from this application */
  9. /* Written by C.K. Haun <TR> */
  10. /* Apple Developer Tech Support */
  11. /* October 1991, Tokyo, Japan */
  12. /* Of course, Copyright 1991-1993, Apple Computer Inc. */
  13.  
  14. /* Does a scrap parse now, when ever the window is redrawn  */
  15. #include "Simple.h"
  16.  
  17. /* prototypes */
  18.  
  19. void ParseScrap(void);
  20. void DrawIndString(short resID, short index);
  21. void WriteNum(long theNum);
  22. WindowPtr FindMyWindow(void);
  23.  
  24. void InitalizeApp(void);
  25. void DoDiskEvents(long dinfo);                              /* hi word is error code, lo word is drive number */
  26. void DrawMain(WindowPtr drawIt);
  27. Boolean DoSelected(long val);
  28. void SizeMain(WindowPtr theWindow, short how);
  29. void InitAEStuff(void);
  30. void DoHighLevel(EventRecord *AERecord);
  31. void DoDaCall(MenuHandle themenu, long theit);
  32. void DoDocumentClick(WindowPtr theWindow, EventRecord *theEvent);
  33. void ActivateMain(WindowPtr theWindow, Boolean on);
  34.  
  35. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  36. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  37. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  38. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  39.  
  40. void SampleHelpDialog(void);
  41.  
  42. WindowPtr AddNewWindow(short theID);
  43.  
  44. void NilProc(void);
  45. /* one external */
  46. extern void _DataInit();                                    /* this is the C initialization code */
  47.  
  48. /* globals */
  49. Boolean gQuit, gInBackground;
  50. unsigned long gMySleep;
  51. ProcessSerialNumber gOurSN;
  52. short gHelpItem;
  53.  
  54.  
  55. #pragma segment Main
  56. main()
  57. {
  58.     EventRecord myEventRecord;
  59.     WindowPtr twindow;
  60.     short fHit;
  61.     windowCHandle tempWCH;
  62.     
  63.     UnloadSeg((Ptr)_DataInit);                              /* throw out setup code */
  64.     InitalizeApp();
  65.     UnloadSeg((Ptr)InitalizeApp);                           /* get rid of my initialization code */
  66.     do {
  67.         WaitNextEvent(everyEvent, &myEventRecord, gMySleep, nil);
  68.         
  69.         switch (myEventRecord.what) {
  70.             case nullEvent:
  71.                 
  72.                 /* no nul processing in this sample */
  73.                 break;
  74.             case updateEvt:
  75.                 /* always check to see if it's my window */
  76.                 /* this may not seem necessary under 7.0, where it's unlikely or impossible for */
  77.                 /* a DA to be in your layer, but there are others */
  78.                 /* who can stick themselves into your window list, */
  79.                 /* BalloonWriter comes quickly to mind */
  80.                 if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  81.                     tempWCH = (windowCHandle)GetWRefCon((WindowPtr)myEventRecord.message);
  82.                     ((*tempWCH)->drawMe)((WindowPtr)myEventRecord.message);
  83.                 }
  84.                 break;
  85.             case mouseDown:
  86.                 /* first see where the hit was */
  87.                 fHit = FindWindow(myEventRecord.where, &twindow);
  88.                 switch (fHit) {
  89.                     Rect limitRect;
  90.                     Str255 tempString;
  91.                     long back;
  92.                     case inDesk:                            /* if they hit in desk, then the process manager */
  93.                         break;                              /* will switch us out, we don't need to do anything */
  94.                     case inMenuBar:
  95.                         DoSelected(MenuSelect(myEventRecord.where));
  96.                         break;
  97.                         
  98.                     case inSysWindow:
  99.                         /* pass to the system */
  100.                         SystemClick(&myEventRecord, twindow);
  101.                         break;
  102.                     case inContent:
  103.                         /* Handle content and control clicks here */
  104.                         if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) { /* don't do this unless we have a window open, silly */
  105.                             windowCHandle clicker;
  106.                             clicker = (windowCHandle)GetWRefCon(twindow);
  107.                             /* jump to the content function stored for this window */
  108.                             HLock((Handle)clicker);         /* lock it down so things don't get stupid */
  109.                             ((*clicker)->clickMe)(twindow, &myEventRecord);
  110.                             HUnlock((Handle)clicker);       /* all done */
  111.                         }
  112.                         break;
  113.                     case inDrag:
  114.                         DragWindow(twindow, myEventRecord.where, &qd.screenBits.bounds);
  115.                         break;
  116.                     case inGrow:
  117.                         /* Call GrowWindow here if you have a grow box */
  118.                         SetPort(twindow);
  119.                         limitRect = qd.screenBits.bounds;
  120.                         limitRect.top = kMinHeight;
  121.                         GetWTitle(twindow, tempString);
  122.                         /* I'm not letting the user shrink the window so */
  123.                         /* small that the title is truncated */
  124.                         limitRect.left = StringWidth(tempString) + 120;
  125.                         back = GrowWindow(twindow, myEventRecord.where, &limitRect);
  126.                         
  127.                         if (back) {
  128.                             if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  129.                                 windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow);
  130.                                 Rect sizeRect = ((WindowPtr)twindow)->portRect;
  131.                                 InvalRect(&sizeRect);
  132.                                 sizeRect.top = sizeRect.bottom - 16;
  133.                                 sizeRect.left = sizeRect.right - 16;
  134.                                 EraseRect(&sizeRect);
  135.                                 InvalRect(&sizeRect);
  136.                                 SizeWindow(twindow, back & 0xffff, back >> 16, true);
  137.                                 ((*tempWCH)->sizeMe)(twindow, fHit);
  138.                             }
  139.                         }
  140.                         InvalRect(&twindow->portRect);
  141.                         
  142.                         break;
  143.                     case inGoAway:
  144.                         /* Click in Close box */
  145.                         if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  146.                             if (TrackGoAway(twindow, myEventRecord.where))
  147.                                 ((*(windowCHandle)((WindowPeek)twindow)->refCon)->closeMe)(twindow);
  148.                         }
  149.                         break;
  150.                     case inZoomIn:
  151.                     case inZoomOut:
  152.                         if (TrackBox(twindow, myEventRecord.where, fHit)) {
  153.                             if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  154.                                 windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow);
  155.                                 SetPort(twindow);
  156.                                 
  157.                                 ZoomWindow(twindow, fHit, true);
  158.                                 InvalRect(&twindow->portRect);
  159.                                 ((*tempWCH)->sizeMe)(twindow, fHit);
  160.                             }
  161.                         }
  162.                 }
  163.             case mouseUp:
  164.                 /* don't care */
  165.                 break;
  166.                 /* same action for key or auto key */
  167.             case keyDown:
  168.             case autoKey:
  169.                 if (myEventRecord.modifiers & cmdKey)
  170.                     DoSelected(MenuKey(myEventRecord.message & charCodeMask));
  171.                 break;
  172.             case keyUp:
  173.                 /* don't care */
  174.                 break;
  175.             case diskEvt:
  176.                 /* I don't do anything special for disk events, this just passes them */
  177.                 /* to a function that checks for an error on the mount */
  178.                 DoDiskEvents(myEventRecord.message);
  179.                 break;
  180.             case activateEvt:
  181.                 if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  182.                     tempWCH = (windowCHandle)GetWRefCon((WindowPtr)myEventRecord.message);
  183.                     ((*tempWCH)->activateMe)((WindowPtr)myEventRecord.message, myEventRecord.modifiers & activeFlag);
  184.                 }
  185.                 break;
  186.             case networkEvt:
  187.                 /* don't care */
  188.                 break;
  189.             case driverEvt:
  190.                 /* don't care */
  191.                 break;
  192.             case app4Evt:
  193.                 switch ((myEventRecord.message >> 24) & 0x0FF) {        /* high byte of message */
  194.                     case suspendResumeMessage:              /* suspend/resume is also an activate/deactivate */
  195.                         gInBackground = (myEventRecord.message & kResumeMask) == 0;
  196.                         if (!gInBackground) {
  197.                             WindowPtr tempWP,myWindow;
  198.                             GetPort(&tempWP);
  199.                             myWindow = FindMyWindow();
  200.                             if(myWindow){
  201.                             SetPort(myWindow);
  202.                             /* make sure the window gets redrawn when we come forward */
  203.                             InvalRect(&myWindow->portRect);
  204.                             }
  205.                             SetPort(tempWP);
  206.                         }
  207.                         break;
  208.                 }
  209.                 break;
  210.             default:
  211.                 break;
  212.                 /* This dispatches high level events (AppleEvents, for example) */
  213.                 /* to our dispatch routine. This is NEW in the event loop for */
  214.                 /* System 7 */
  215.             case kHighLevelEvent:
  216.                 DoHighLevel(&myEventRecord);
  217.                 break;
  218.                 
  219.         }
  220.     }
  221.             while (gQuit != true);
  222.     
  223. }
  224.  
  225. /* DoDaCall opens the requested DA. It's here as a seperate routine if you'd */
  226. /* like to perform some action or just know when a DA is opened in your */
  227. /* layer. Can be handy to track memory problems when a DA is opened */
  228. /* with an Option-open */
  229. void DoDaCall(MenuHandle themenu, long theit)
  230. {
  231.     long qq;
  232.     char DAname[255];
  233.     GetItem(themenu, theit, &DAname);
  234.     qq = OpenDeskAcc(DAname);
  235. }
  236.  
  237. /* end DoDaCall */
  238.  
  239. /* DoDiskEvents just checks the error code from the disk mount, */
  240. /* and puts up the 'Format' dialog (through DIBadMount) if need be */
  241. /* You can do much more here if you care about what disks are */
  242. /* in the drive */
  243. void DoDiskEvents(long dinfo)                               /* hi word is error code, lo word is drive number */
  244. {
  245.     short hival, loval, tommy;
  246.     Point fredpoint =  {
  247.         40, 40
  248.     };
  249.     hival = HiWord(dinfo);
  250.     loval = LoWord(dinfo);
  251.     if (hival != noErr)                                     /* something happened */ {
  252.         tommy = DIBadMount(fredpoint, dinfo);
  253.     }
  254. }
  255.  
  256. /* draws my window. Pretty simple */
  257. void DrawMain(WindowPtr drawIt)
  258. {
  259.     RgnHandle tempRgn;
  260.     Rect scratchRect;
  261.     BeginUpdate(drawIt);
  262.     SetPort(drawIt);
  263.     /* clear what's there */
  264.     EraseRgn(drawIt->visRgn);
  265.     scratchRect = drawIt->portRect;
  266.     scratchRect.top = scratchRect.bottom - 15;
  267.     scratchRect.left = scratchRect.right - 15;
  268.     tempRgn = NewRgn();
  269.     GetClip(tempRgn);
  270.     ClipRect(&scratchRect);
  271.     DrawGrowIcon(drawIt);
  272.     SetClip(tempRgn);
  273.     DisposeRgn(tempRgn);
  274.     /* draw some text */
  275.     ParseScrap();
  276.     
  277.     EndUpdate(drawIt);
  278. }
  279.  
  280. /* my menu action taker. It returns a Boolean which I usually ignore, but it */
  281. /* mught be handy someday */
  282. /* I usually use it in an application to determine if a keystroke was accepted */
  283. /* by a menu or whether it should be passed along to any other key acceptors */
  284. Boolean DoSelected(long val)
  285. {
  286.     short loval, hival;
  287.     Boolean returnVal = false;
  288.     loval = LoWord(val);
  289.     hival = HiWord(val);
  290.     
  291.     switch (hival) {                                        /* switch off the menu number selected */
  292.         case kAppleMenu:                                    /* Apple menu */
  293.             if (loval != 1) {                               /* if this was not About, it's a DA */
  294.                 DoDaCall(GetMHandle(kAppleMenu), loval);
  295.             } else {
  296.                 Alert(kAboutBox, nil);                      /* do about box */
  297.             }
  298.             returnVal = true;
  299.             break;
  300.         case kFileMenu:                                     /* File menu */
  301.             switch (loval) {
  302.                 case kQuitItem:
  303.                     gQuit = true;                           /* only item */
  304.                     returnVal = true;
  305.                     break;
  306.                 default:
  307.                     break;
  308.             }
  309.             break;
  310.         case kEditMenu:
  311.             /* edit menu junk */
  312.             /* don't care */
  313.             switch (loval) {
  314.             default:
  315.                 break;
  316.             }
  317.             break;
  318.         case kToolsMenu:
  319.             /* add all your test stuff here */
  320.             switch (loval) {
  321.             default:
  322.                 break;
  323.             }
  324.             break;
  325.         case kHMHelpMenuID:                                 /* Defined in Balloons.h */
  326.             /* I only care about this item. If anything else is returned here, I don't know what */
  327.             /* it is, so I leave it alone. Remember, the Help Manager chapter says that */
  328.             /* Apple reserves the right to add and change things in the Help menu */
  329.             if (loval == gHelpItem)
  330.                 SampleHelpDialog();
  331.             break;
  332.             
  333.     }
  334.     HiliteMenu(0);
  335.     return(returnVal);
  336. }
  337.  
  338. void DoDocumentClick(WindowPtr theWindow, EventRecord *theEvent)
  339. {
  340.     
  341. }
  342.  
  343. /* InitAEStuff installs my appleevent handlers */
  344. void InitAEStuff(void)
  345. {
  346.     AEinstalls HandlersToInstall[] =  {
  347.         {
  348.             kCoreEventClass, kAEOpenApplication, AEOpenHandler
  349.         },  {
  350.             kCoreEventClass, kAEOpenDocuments, AEOpenDocHandler
  351.         },  {
  352.             kCoreEventClass, kAEQuitApplication, AEQuitHandler
  353.         },  {
  354.             kCoreEventClass, kAEPrintDocuments, AEPrintHandler
  355.         }, 
  356.         /* The above are the four required AppleEvents. */
  357.         
  358.     };
  359.     
  360.     OSErr aevtErr = noErr;
  361.     long aLong = 0;
  362.     Boolean gHasAppleEvents = false;
  363.     /* Check this machine for AppleEvents. If they are not here (ie not 7.0)
  364.     * then we exit */
  365.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
  366.     /* The following series of calls installs all our AppleEvent Handlers.
  367.     * These handlers are added to the application event handler list that 
  368.     * the AppleEvent manager maintains. So, whenever an AppleEvent happens
  369.     * and we call AEProcessEvent, the AppleEvent manager will check our
  370.     * list of handlers and dispatch to it if there is one.
  371.     */
  372.     if (gHasAppleEvents) {
  373.         register qq;
  374.         for (qq = 0; qq < ((sizeof(HandlersToInstall) / sizeof(AEinstalls))); qq++) {
  375.             aevtErr = AEInstallEventHandler(HandlersToInstall[qq].theClass, HandlersToInstall[qq].theEvent,
  376.                                             HandlersToInstall[qq].theProc, 0, false);
  377.             if (aevtErr) {
  378.                 ExitToShell();                              /* just fail, baby */
  379.             }
  380.         }
  381.     } else {
  382.         ExitToShell();
  383.     }
  384. }
  385.  
  386. /* end InitAEStuff */
  387. /* I'm not doing error handling in this sample for clarities sake, you should. Hah, */
  388. /* easy for me to say, huh? */
  389. void DoHighLevel(EventRecord *AERecord)
  390. {
  391.     OSErr myErr;
  392.     myErr = AEProcessAppleEvent(AERecord);
  393.     
  394. }
  395.  
  396. /* end DoHighLevel */
  397.  
  398. /* This is the standard Open Application event. */
  399. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  400. {
  401.     WindowPtr myWindow;
  402.  
  403. #pragma unused (messagein,reply,refIn)
  404.     /* we of course don't do anything here in this simple app */
  405.     /* except open our window */
  406.     myWindow = AddNewWindow(kDocWindowResID);
  407.     
  408.     return(noErr);
  409. }
  410.  
  411. /* end AEOpenHandler */
  412.  
  413. /* Open Doc, opens our documents. Remember, this can happen at application start AND */
  414. /* anytime else. If your app is up and running and the user goes to the desktop, hilites one */
  415. /* of your files, and double-clicks or selects Open from the finder File menu this event */
  416. /* handler will get called. Which means you don't do any initialization of globals here, or */
  417. /* anything else except open then doc. */
  418. /* SO-- Do NOT assume that you are at app start time in this */
  419. /* routine, or bad things will surely happen to you. */
  420.  
  421. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  422. {
  423. #pragma unused (messagein,refIn,reply)
  424.     /* we of course don't do anything here */
  425.     return(errAEEventNotHandled);                           /* we have no docs, so no odoc events should come to us */
  426. }
  427.  
  428. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  429. {                                                           /* no printing handler in yet, so we'll ignore this */
  430.     /* the operation is functionally identical to the ODOC event, with the additon */
  431.     /* of calling your print routine. */
  432. #pragma unused (messagein,refIn,reply)
  433.     /* we of course don't do anything here */
  434.     return(errAEEventNotHandled);                           /* we have no docs, so no pdoc events should come to us */
  435. }
  436.  
  437. /* Standard Quit event handler, to handle a Quit event from the Finder, for example. */
  438. /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life. */
  439. /* OK, it's a few months after I wrote that comment, and I've seen a lot of code */
  440. /* come through DTS that calls ExitToShell from quit handlers. Let me explain... */
  441. /* When an AppleEvent Handler is called (like this quit handler) you are ALMOST */
  442. /* 100% in your application world. A5 is right, you can call any toolbox function, */
  443. /* you can call your own routines, everything _seems_ like you are in complete */
  444. /* control. Well, almost but not quite. The routine has been dispatch to from the */
  445. /* AppleEvent Manager's space, so you _must_ return to that at some point! */
  446. /* Which is why you can't call ETS from here. When you call ExitToShell from an */
  447. /* AE Handler, the most likely thing that happens is the FInder quits, and your */
  448. /* application keeps running. Which ain't what you want, y'know? */
  449. /* so, DON'T CALL EXITTOSHELL FROM AN APPLEEVENT HANDLER!!!!!!!!!!!!!! */
  450. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  451. {
  452. #pragma unused (messagein,refIn,reply)
  453.     gQuit = true;
  454.     return(noErr);
  455. }
  456.  
  457.  
  458. /* This is my sample help dialog. Does not do anything, expand as you need */
  459. void SampleHelpDialog(void)
  460. {
  461.     DialogPtr tdial = GetNewDialog(kSampHelp, nil, (WindowPtr)-1);
  462.     short itemhit = 0;
  463.     while (itemhit != 1) {
  464.         ModalDialog((ModalFilterProcPtr)nil, &itemhit);
  465.     }
  466.     DisposDialog(tdial);
  467. }
  468.  
  469.  
  470. #pragma segment Initialize
  471. void InitalizeApp(void)
  472. {
  473.     Handle myMenu;
  474.     MenuHandle helpHandle, appleMenuHandle;
  475.     StringHandle helpString;
  476.     short count;
  477.     long vers;
  478.     MaxApplZone();
  479.     InitGraf((Ptr)&qd.thePort);
  480.     InitFonts();
  481.     InitWindows();
  482.     InitMenus();
  483.     TEInit();
  484.     InitDialogs(nil);
  485.     InitCursor();
  486.     /* Check system version */
  487.     Gestalt(gestaltSystemVersion, &vers);
  488.     vers = (vers >> 8) & 0xf;                               /* shift result over and mask out major version number */
  489.     if (vers < 7) {
  490.         StopAlert(kBadSystem, nil);
  491.         ExitToShell();
  492.     }
  493.     InitAEStuff();
  494.     /* set up my menu junk */
  495.     myMenu = GetNewMBar(kMBarID);
  496.     SetMenuBar(myMenu);
  497.     appleMenuHandle = GetMHandle(kAppleMenu);
  498.     AddResMenu(appleMenuHandle, 'DRVR');
  499.     
  500.     /* now install my Help menu item in the Help Manager's menu */
  501.     HMGetHelpMenuHandle(&helpHandle);                       /* Get the Hlpe menu handle */
  502.     count = CountMItems(helpHandle);                        /* How many items are there? */
  503.     helpString = GetString(kHelpString);                    /* get my help string */
  504.     DetachResource(helpString);                             /* detach it */
  505.     HNoPurge(helpString);
  506.     MoveHHi((Handle)helpString);
  507.     HLock((Handle)helpString);
  508.     InsMenuItem(helpHandle, (Ptr)*helpString, count + 1);       /* insert my item in the Help menu */
  509.     gHelpItem = CountMItems(helpHandle);                    /* The number of the item */
  510.     
  511.     DrawMenuBar();
  512.     GetCurrentProcess(&gOurSN);                             /* Get our process serial number for later use, if needed */
  513.     
  514. }
  515.  
  516.  
  517. #pragma segment Main
  518. WindowPtr AddNewWindow(short theID)
  519. {
  520.     windowCHandle setControls;
  521.     WindowPtr tempWP;
  522.     short cnt = 0;
  523.     Str31 wtitle;
  524.     tempWP = GetNewWindow(theID, 0, (WindowPtr)-1);         /* get a new window */
  525.     ((WindowPeek)tempWP)->windowKind = kMyDocumentWindow;       /* mark it as my document window */
  526.     setControls = (windowCHandle)NewHandleClear(sizeof(windowControl));     /* add our control structure to it */
  527.     SetWRefCon(tempWP, (long)setControls);                  /* stop stuffing refCon directly <ckh 1.0.3> */
  528.     HLock((Handle)setControls);                             /* lock it down while we fill it*/
  529.     
  530.     /* add pointers to our procedures for drawing, saving, and closing */
  531.     /* This way, all I need is one dispatch point for drawing, closing */
  532.     /* or whatever, I don't have to case off the window kind to go to the */
  533.     /* correct routine. Kinda like object-oriented programming, but I won't */
  534.     /* admit that. */
  535.     (*setControls)->drawMe = DrawMain;
  536.     (*setControls)->clickMe = DoDocumentClick;
  537.     (*setControls)->sizeMe = SizeMain;
  538.     (*setControls)->activateMe = ActivateMain;
  539.     (*setControls)->generalData = NewHandle(0);
  540.     
  541.     return(tempWP);
  542. }
  543.  
  544. void ActivateMain(WindowPtr theWindow, Boolean on)
  545. {WindowPtr tempWP;
  546. GetPort(&tempWP);
  547. SetPort(theWindow);
  548. /* make sure the window gets redrawn when it's activated or deactivated */
  549. InvalRect(&theWindow->portRect);
  550. SetPort(tempWP);
  551.     
  552. }
  553.  
  554. void SizeMain(WindowPtr theWindow, short how)
  555. {
  556.     WindowPtr tempWP;
  557.     GetPort(&tempWP);
  558.     InvalRect(&theWindow->portRect);
  559.     SetPort(tempWP);
  560. }
  561.  
  562. void NilProc(void)
  563. {
  564.     
  565. }
  566.  
  567. /* walks the current scrap Handle and spits out */
  568. /* the contents */
  569. void ParseScrap(void)
  570. {
  571.     OSType currentType;
  572.     long dataLength;
  573.     short vPos = 20;
  574.     Size lengthOfHandle;
  575.     /* get the basic scrap information */
  576.     PScrapStuff theScrap = InfoScrap();
  577.     /* get the scrap handle */
  578.     Handle scrapHandle = theScrap->scrapHandle;
  579.     /* make a pointer to it */
  580.     Ptr theScrapPtr;
  581.     long currentLength;
  582.     Str255 theString;
  583.     Str15 theOSTypeString;
  584.     OSType *theOSTypeStrPtr;
  585.     /* OS type will always be 4 */
  586.     theOSTypeString[0] = 4;
  587.     /* don't do anything if the handle doesn't exist */
  588.     if (scrapHandle) {
  589.         HLock(scrapHandle);
  590.         theScrapPtr = *scrapHandle;
  591.         MoveTo(10, vPos);
  592.         DrawIndString(kGeneralStrings, 1);
  593.         /* walk through all the types in the scrap */
  594.         vPos += 15;
  595.         /* how big the current scrap handle is */
  596.         lengthOfHandle = GetHandleSize(scrapHandle);
  597.         if (lengthOfHandle) {
  598.             do {
  599.                 MoveTo(10, vPos);
  600.                 DrawIndString(kGeneralStrings, 2);
  601.                 currentType = *((OSTypePtr)theScrapPtr);        /* get this type */
  602.                 /* block move it so 68000 machines don't b*tch */
  603.                 /* about odd addresses */
  604.                 BlockMove((Ptr)¤tType,(Ptr)&theOSTypeString[1],4);
  605.                 /* draw the type */
  606.                 DrawString(&theOSTypeString);
  607.                 theScrapPtr += 4;                           /* move 4 bytes */
  608.                 dataLength = *((long *)theScrapPtr);        /* length of this type */
  609.                 DrawIndString(kGeneralStrings, 3);
  610.                 /* write the lenght */
  611.                 WriteNum(dataLength);
  612.                 /* next verticle */
  613.                 vPos += 15;
  614.                 
  615.                 theScrapPtr += 4;                           /* now pointing at the data */
  616.                 theScrapPtr += dataLength;                  /* mvoe to the next type */
  617.                 /* round up, since the handle will always be even */
  618.                 currentLength =    theScrapPtr - *scrapHandle;
  619.                 /* if odd, add 1 */
  620.                 if(currentLength & 0x1)currentLength++;
  621.                 
  622.                 /* are we at the end of the data??? */
  623.                 if (currentLength >= lengthOfHandle) {
  624.                     break;                                  /* at the end of the handle, break out */
  625.                 }
  626.             }
  627.                     while (true);
  628.         }
  629.         HUnlock(scrapHandle);
  630.         
  631.     }
  632. }
  633.  
  634. void DrawIndString(short resID, short index)
  635. {
  636.     Str255 theString;
  637.     GetIndString(theString, resID, index);
  638.     DrawString(theString);
  639.     
  640. }
  641.  
  642. void WriteNum(long theNum)
  643. {
  644.     Str32 theNumAsString;
  645.     NumToString(theNum, &theNumAsString);
  646.     DrawString(theNumAsString);
  647.     
  648. }
  649.  
  650.  
  651. WindowPtr FindMyWindow(void)
  652. {
  653. WindowPtr tempWP = FrontWindow();
  654. while(tempWP){
  655. if(((WindowPeek)tempWP)->windowKind == kMyDocumentWindow)
  656. break;
  657. else
  658.     tempWP = (WindowPtr)((WindowPeek)tempWP)->nextWindow;
  659. }
  660. return(tempWP);
  661.  
  662. }